import type {createMessageProps,MessageContext} from "./types";
import {render,h,shallowReactive} from 'vue'
import MessageConstructor from './MessageMain.vue'
import useZIndex from '../../hooks/useZindex';

let seed=1
//渲染的时候（2）还没有插入实例（1），渲染中调用getLastBottomOffset找实例找不到，导致定位失败
// 所以要把实例数组设置为响应式的，改变后重新触发getLastBottomOffset
//shallowreactive只有跟级别的属性是响应式提高性能
const instances:MessageContext[]=shallowReactive([])
export const createMessage=(props: createMessageProps)=>{
  const {nextZIndex}=useZIndex()
  const id=`message_${seed++}`
  const container=document.createElement('div')
  // 关闭后自动清除节点
  const destory =()=>{
    //删除数组中的实例
    const idx =instances.findIndex(instance=>instance.id===id)
    if(idx===-1) return
    instances.splice(idx,1)
    render(null,container)
  }
  //手动调用删除，其实就是调整组件中的visible的值
  //visible是通过expose传出来的
  const manualDestroy=()=>{
    const instance =instances.find(instance=>instance.id===id)
    if(instance){
      instance.vm.exposed!.visible.value=false
    }
  }
  const newProps={
    ...props,
    id,
    zIndex:nextZIndex(),
    onDestory:destory
  }
  const vnode=h(MessageConstructor,newProps)
  render(vnode,container)                                   //(2)
  
  // !表示非空断言操作符 变量不为null或者undefined
  document.body.appendChild(container.firstElementChild!)
  // 获取组件实例
  const vm=vnode.component!
  const instance={
    id,
    vnode,
    //内部实例插入到数组中，实例信息里面含有暴露出去的bottomOffset
    vm,
    props:newProps,
    destory:manualDestroy
  }
  instances.push(instance)                                  //(1)
  return instance
}

export const getLastInstance=()=>{
  return instances.at(-1)
}

export const getLastBottomOffset=(id:string)=>{
  const idx=instances.findIndex(instance=>instance.id===id)
  if (idx<=0){
    return 0
  }else{
    const prev=instances[idx-1]
    return prev.vm.exposed!.bottomOffset.value
  }
}